package com.soup.lab.basic.iso.executor;

import java.util.Collection;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.function.Function;

public interface KeyPickCallable<K, V> extends Callable<V> {

    /**
     * 获取互斥键的集合
     *
     * 如果集合中的任意键所属的任务正在中，则需等待它们执行完成。
     *
     * @return
     */
    Collection<K> getKeys();

    static <T, K, V> KeyPickCallable<K, V> create(T target, Function<T, Collection<K>> keyGetter, Function<T, V> callFunc) {
        return new KeyPickCallable.SimpleKeyPickCallable<>(target, keyGetter.apply(target), callFunc);
    }

    static <T, K, V> KeyPickCallable<K, V> create(T target, Collection<K> keys, Function<T, V> callFunc) {
        return new KeyPickCallable.SimpleKeyPickCallable<>(target, keys, callFunc);
    }

    class SimpleKeyPickCallable<T, K, V> implements KeyPickCallable<K, V> {
        private final Function<T, V> callFunc;
        private final Collection<K> keys;
        private final T target;

        private SimpleKeyPickCallable(T target, Collection<K> keys, Function<T, V> callFunc) {
            this.target = Objects.requireNonNull(target);
            this.keys = keys;
            this.callFunc = Objects.requireNonNull(callFunc);
        }

        @Override
        public Collection<K> getKeys() {
            return keys;
        }

        @Override
        public V call() {
            return callFunc.apply(target);
        }
    }

}
